﻿namespace ScrumLite.WebUx.Controllers
{
    using System.Configuration;
    using System.Web.Mvc;
    using ScrumLite.Services;
    using ScrumLite.WebUx.Models;
    using System.Collections.ObjectModel;
    using ScrumLite.Services.Contracts;
    using System.Collections.Generic;
    using System.Linq;
    using System;
    using System.Globalization;
    using GoogleChartSharp;
    using ScrumLite.Gateways;
    using System.Web.Routing;

    public class ReviewsController : ContextBaseController
    {
        IReviewsService reviewService;

        public ReviewsController()
            : this(new ReviewsServiceClient(), new ProjectsServiceClient(), new ProfileServiceClient())
        {
        }

        public ReviewsController(IReviewsService reviewService, Services.IProjectsService projectService, IProfileService profileService)
            : base(profileService, projectService)
        {
            this.reviewService = reviewService;
        }

        public void List(string projectId)
        {
            ReviewListViewData data = new ReviewListViewData(new Collection<Review>(reviewService.GetReviews(projectId)))
            {
                ProjectName = Projects.GetProjectName(projectId),
                ProjectId = projectId,
                ViewTitle = "Reviews"
            };

            RenderView("List", data);
        }

        public void New(string projectId)
        {
            Review review = new Review
            {
                OccurredOn = DateTime.Now,
                EvidenceUrl = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", Projects.GetProjectRepository(projectId), ConfigurationManager.AppSettings["defaultReviewPath"])
            };

            ReviewsWriteViewData data = new ReviewsWriteViewData
            {
                Review = review,
                ProjectName = Projects.GetProjectName(projectId),
                ProjectId = projectId,
                ViewTitle = "Add New Review"
            };

            RenderView("Write", data);
        }

        public void Edit(string projectId, string id)
        {
            Review review = reviewService.GetReview(id);

            ReviewsWriteViewData data = new ReviewsWriteViewData
            {
                Review = review,
                ProjectName = Projects.GetProjectName(projectId),
                ProjectId = projectId,
                ViewTitle = "Edit Review"
            };

            RenderView("Write", data);
        }

        public void Save(string projectId, string id, DateTime occurredOn, string conductedBy, string evidencePath)
        {
            Review review = new Review
            {
                ProjectId = new Guid(projectId),
                OccurredOn = occurredOn,
                ConductedBy = conductedBy,
                EvidenceUrl = evidencePath
            };

            if (String.IsNullOrEmpty(id))
            {
                reviewService.AddReview(review);
            }
            else
            {
                review.Id = new Guid(id);
                reviewService.UpdateReview(review);
            }

            RedirectToAction(new { Action = "List" });
        }

        public void ReviewsMetrics(string projectId)
        {
            ReviewsMetricsData data = new ReviewsMetricsData(reviewService.GetReviewsByWeek(projectId))
            {
                ProjectName = Projects.GetProjectName(projectId)
            };
            data.GChartReviewsLine = CreateWeeklyReviewsLineUrl(data);
            data.ProjectId = projectId;
            data.ProjectName = Projects.GetProjectName(projectId);
            data.ViewTitle = "Reviews Metrics";
            RenderView("ReviewsMetrics", data);
        }

        private static string CreateWeeklyReviewsLineUrl(ReviewsMetricsData data)
        {
            if (data.WeeklyRequests.Count() == 0)
            {
                return String.Format(CultureInfo.InvariantCulture, "/{0}/{1}", ConfigurationManager.AppSettings["SiteImagesPath"], "chart_EmptyWeeklyReviewsLine.png");
            }
            else
            {
                LineChart chartBuilder = new LineChart(500, 250, LineChartType.SingleDataSet);
                chartBuilder.AddLineStyle(new LineStyle(3, 1, 0));
                chartBuilder.AddLineStyle(new LineStyle(1, 6, 3));
                chartBuilder.SetTitle("Weekly reviews");
                chartBuilder.SetLegend(new string[] { "Reviews", "Average" });
                chartBuilder.SetDataSetColors(new string[] { "ff0000", "0000ff" });

                List<float> chartData = new List<float>();
                List<string> weekLabels = new List<string>();
                foreach (KeyValuePair<int, int> week in data.WeeklyRequests)
                {
                    chartData.Add(week.Value);
                    weekLabels.Add(string.Format(CultureInfo.InvariantCulture, "W{0}", week.Key));
                }

                ChartAxis weeklyAxis;
                if (weekLabels.Count > 0)
                {
                    weeklyAxis = new ChartAxis(ChartAxisType.Bottom, weekLabels.ToArray());
                }
                else
                {
                    weeklyAxis = new ChartAxis(ChartAxisType.Bottom, new string[] { "." });
                }
                chartBuilder.AddAxis(weeklyAxis);

                float maxValueRange = 0;
                if (chartData.Count > 0)
                {
                    maxValueRange = chartData.Max();
                }
                int maxValueLabel = (Convert.ToInt32(maxValueRange / 10) + 1) * 10;
                ChartAxis unitAxis = new ChartAxis(ChartAxisType.Left);
                unitAxis.SetRange(0, maxValueLabel);
                chartBuilder.AddAxis(unitAxis);

                double? average = 0;
                if (data.WeeklyRequests.Count > 0)
                {
                    average = data.WeeklyRequests.Average(w => w.Value);
                }
                List<float[]> allData = new List<float[]>();
                allData.Add(chartData.ToArray());
                allData.Add(new float[] { (float)average, (float)average });
                chartBuilder.SetData(allData, maxValueLabel);

                return chartBuilder.GetUrl();
            }
        }
    }
}
